//App.js
import requestUtil from "./api/request"
import API from "./api/http.api"

let SocketTask;
let reconnectLimit = 1

// 文字转语音插件
const plugin = requirePlugin("WechatSI")

// 声音播放管理器
const audioPlayer = wx.createInnerAudioContext();

App({
  globalData: {
    loadFinish: false,
    socketStatus: 'closed',
    openId: null,
    userType: null,
    sessionId: null,
    userInfo: null,
    repeatLogin: false,
    // 禁用服务端的预约大厅
    disableHell: false
  },

  onLaunch: function() {
    console.log("app--------------------------------onLaunch")
    this.login()

    // 快速获取格式化过的当前时间，格式 2020/6/24 15:37
    Date.prototype.format = function() {
      let time = new Date();

      let fullYear = time.getFullYear();
      let date = time.getDate();
      date = date < 10 ? "0" + String(date) : date
      let month = time.getMonth();
      month = month < 10 ? "0" + String(month) : month
      let hours = time.getHours();
      hours = hours < 10 ? "0" + String(hours) : hours
      let minutes = time.getMinutes();
      minutes = minutes < 10 ? "0" + String(minutes) : minutes
      let seconds = time.getSeconds()
      seconds = seconds < 10 ? "0" + String(seconds) : seconds
      return fullYear + "-" + month + "-" + date + " " + hours + ":" + minutes + ":" + seconds;
    }

  },

  onShow: function() {
    console.log("app--------------------------------onshow")
    // 切前台检查连接是否已断开，已断开则重连（this.globalData.openId === null 说明还未登录，不需要连接，onload 中会连接）
    if (this.globalData.socketStatus === 'closed' && this.globalData.openId !== null) {
      this.linkSocket();
    }
  },

  onHide: function() {
    console.log("onhide")
  },

  login: function() {
    wx.showLoading({
      title: '加载中',
    })

    var that = this

    wx.login({
      success: res => {
        requestUtil.post(API.LOGIN, {
          'code': res.code
        }).then(res => {

          console.log(res)

          API.REQUEST_HEADER = {
            'sessionId': res.data.sessionId,
            'openId': res.data.openId
          }

          // 刷新 openId 缓存
          that.globalData.openId = res.data.openId;
          // 刷新 sessionId 缓存
          that.globalData.sessionId = res.data.sessionId;
          if (res.data.userType !== null) {
            // 刷新 userType 缓存
            that.globalData.userType = res.data.userType

            // 连接 websocket
            if (that.globalData.socketStatus === 'closed') {
              that.linkSocket();
            }
          }

          const userInfo = {
            nickName: res.data.nickName,
            avatarUrl: res.data.avatarUrl
          }

          that.globalData.userInfo = userInfo
          that.globalData.registeredPhone = res.data.registeredPhone

          that.globalData.loadFinish = true
        }).catch(err => {
          console.log(err)
          wx.hideLoading()
          wx.showModal({
            title: '错误',
            content: '小程序加载失败，请点击下方的确定按钮重试',
            confirmText: '确定',
            success: function(res) {
              if (res.confirm) {
                that.onLaunch();
              }
            }
          })
        })
      }
    })
  },

  // 连接 socket
  linkSocket() {
    let that = this
    SocketTask = wx.connectSocket({
      header: {
        "sessionId": that.globalData.sessionId,
        "openId": that.globalData.openId
      },
      url: API.WEB_SOCKET_HOST + that.globalData.openId + "/" + that.globalData.userType,
      success: function() {
        that.initSocketEventHandle();

      }
    })
    this.globalData.SocketTask = SocketTask
  },

  // 绑定与 socket 相关的各种事件
  initSocketEventHandle() {
    //打开时的动作
    var that = this
    wx.onSocketOpen(() => {
      console.log('WebSocket 已打开')
      this.globalData.socketStatus = 'connected';

      that.heartCheck.reset().start()
    })

    //断开时的动作
    wx.onSocketClose((res) => {
      console.log('WebSocket 已关闭')
      that.heartCheck.reset()
      this.globalData.socketStatus = 'closed'
      if (this.globalData.repeatLogin == true) {
        this.globalData.repeatLogin == false
      } else {
        this.reconnect()
      }
    })

    //报错时的动作
    wx.onSocketError(error => {
      console.error('socket error:', error)
      wx.showToast({
        title: "无法连接消息服务器，请检查网络后重新进入",
        icon: 'none',
        duration: 2000,
        "mask": true
      })
    })

    // 监听服务器推送的消息
    wx.onSocketMessage(message => {

      // 判断是否是服务器响应的心跳包数据
      if (message.data == "pong") {
        that.heartCheck.reset().start();
        return
      }

      console.log("【websocket收到到消息】内容如下：");
      console.log(message);

      var msg = JSON.parse(message.data)

      // 判断是否是服务端发送的重复登录提示
      if (msg.code == 20006) {
        this.globalData.repeatLogin = true;
        return
      }

      if (msg.message_property == 'appointment_accepted') {
        that.textToSpeech('您的预约已被志愿者接受，再次点击预约志愿者可与接受预约的志愿者进行沟通').then((res) => {
          audioPlayer.src = res
          audioPlayer.play()
        })
        return
      }

      const pages = getCurrentPages();
      console.log(pages)
      const currentPage = pages[pages.length - 1]; //当前页面
      // 判断当前页面有没有onMessage方法，有则调用
      if (currentPage != undefined && currentPage.onMessage != undefined) {
        currentPage.onMessage(message);
      }
    })
  },

  //关闭信道
  closeSocket() {
    const that = this
    if (this.globalData.socketStatus === 'connected') {
      wx.closeSocket({
        success: () => {
          that.heartCheck.reset()
          this.globalData.socketStatus = 'closed'
        }
      })
    }
  },

  // 断线重连，五秒重试一次
  reconnect() {
    if (this.globalData.socketStatus === 'connected') return;
    if (this.lockReconnect) return;
    this.lockReconnect = true;
    clearTimeout(this.timer)
    this.timer = setTimeout(() => {
      console.log("尝试第 " + reconnectLimit + " 次重连")
      reconnectLimit = reconnectLimit + 1
      this.linkSocket();
      this.lockReconnect = false;
    }, 5000);
  },

  // 加入心跳机制，nginx在60秒无数据的情况下会切断连接，每10秒发送一次数据给服务器
  // 既能将长连接维持下去，又能在服务器无响应时及时重连
  heartCheck: {
    timeout: 30000,
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function() {
      clearTimeout(this.timeoutObj);
      clearTimeout(this.serverTimeoutObj);
      return this;
    },
    start: function() {
      // 10 秒后发送一次数据
      this.timeoutObj = setTimeout(() => {
        // console.log("发送ping");
        wx.sendSocketMessage({
          data: "ping",
        });
        // 只有当服务端未响应心跳包时才会触发，不然永远不会触发
        this.serverTimeoutObj = setTimeout(() => {
          wx.closeSocket({
            success: () => {
              this.globalData.socketStatus = 'closed'
            }
          })
        }, this.timeout);
      }, this.timeout);
    }
  },

  // 文本转语音
  textToSpeech: function(content) {
    return new Promise((resolve, reject) => {
      plugin.textToSpeech({
        lang: "zh_CN",
        tts: true,
        content: content,
        success: function(res) {
          console.log("succ tts", res.filename)
          resolve(res.filename)
        },
        fail: function(res) {
          reject(res)
        }
      })
    })
  },

  // 发送消息函数
  sendMessage() {
    if (this.globalData.socketStatus === 'connected') {
      //自定义的发给后台识别的参数 ，我这里发送的是name
      wx.sendSocketMessage({
        data: "{\"name\":\"" + wx.getStorageSync('openId') + "\"}"
      })
    }
  },
})